/**
 * $RCSfile$
 * $Revision: 1710 $
 * $Date: 2005-07-26 11:56:14 -0700 (Tue, 26 Jul 2005) $
 *
 * Copyright (C) 2004-2008 Jive Software. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.kingray.openfire.plugin.servlet;

import com.kingray.openfire.plugin.*;
import com.kingray.openfire.plugin.vo.GroupVO;
import com.kingray.openfire.plugin.vo.UserStatusVO;
import com.xiongyingqi.openfire.util.SequenceGenerator;

import gnu.inet.encoding.Stringprep;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JsonConfig;

import org.jivesoftware.admin.AuthCheckFilter;
import org.jivesoftware.openfire.PresenceManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.group.Group;
import org.jivesoftware.openfire.group.GroupManager;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;

/**
 * Servlet that addition/deletion/modification of the users info in the system.
 * Use the <b>type</b> parameter to specify the type of action. Possible values
 * are <b>add</b>,<b>delete</b> and <b>update</b>.
 * <p>
 * <p/>
 * The request <b>MUST</b> include the <b>secret</b> parameter. This parameter
 * will be used to authenticate the request. If this parameter is missing from
 * the request then an error will be logged and no action will occur.
 * 
 * @author Justin Hunt
 */
public class UserServiceServlet extends HttpServlet {
	public static final Logger log = LoggerFactory
			.getLogger(UserServiceServlet.class);
	private KingrayServicePlugin plugin;

	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		super.init(servletConfig);
		plugin = (KingrayServicePlugin) XMPPServer.getInstance()
				.getPluginManager().getPlugin("kingrayplugin");
		log.debug("UserServiceServlet init ------------ ");
		// Exclude this servlet from requiring the user to login
		AuthCheckFilter.addExclude("kingrayplugin/userservice");
	}

	@Override
	public void destroy() {
		super.destroy();
		// Release the excluded URL
		AuthCheckFilter.removeExclude("kingrayplugin/userservice");
	}

	/**
	 * 显示获取所有用户页面
	 * 
	 * @param request
	 * @param response
	 */
	private void showUserPage(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		response.sendRedirect("pages/user_list.jsp");
	}
	/**
	 * 获取所有用户
	 * 
	 * @param request
	 * @param response
	 */
	private void doGetAllUsers(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		Collection<Group> groups = GroupManager.getInstance().getGroups();
		Collection<GroupVO> groupVOs = new LinkedHashSet<GroupVO>(); // 存放分组集合
		for (Iterator iterator = groups.iterator(); iterator.hasNext();) {
			Group group = (Group) iterator.next();
			Collection<JID> jids = group.getMembers();
			Collection<UserStatusVO> userStatusVOs = new ArrayList<UserStatusVO>(); // 存放每组用户及状态集合
			Iterator iterator2 = jids.iterator();
			for (; iterator2.hasNext();) {
				JID jid = (JID) iterator2.next();
				boolean isLocal = XMPPServer.getInstance().isLocal(jid);
                User user = null;
                if (isLocal) {
                    try {
                        user = UserManager.getInstance().getUser(jid.getNode());
                    }
                    catch (UserNotFoundException unfe) {
                        // Ignore.
                    }
                }
                
				if(user != null){
					//设置用户状态
					XMPPServer xmppServer = XMPPServer.getInstance();
					PresenceManager presenceManager = xmppServer.getPresenceManager();
					Presence presence = presenceManager.getPresence(user);
					UserStatusVO userStatusVO = new UserStatusVO(user, presence);
					userStatusVOs.add(userStatusVO);
				} else {
					log.debug("user:" + user);
					log.debug("user null!");
				}
			}
			GroupVO groupVO = new GroupVO(group, userStatusVOs);
			groupVOs.add(groupVO);
		}
		JsonConfig config = new JsonConfig();
		config.setExcludes(new String[]{"creationDate", "modificationDate"});
		JSONArray jsonArray = JSONArray.fromObject(groupVOs);
		try {
			response.setContentType("text/plain;charset=UTF-8");
//			response.setContentType("application/x-javascript");
//			response.setContentType("text/html;charset=UTF-8");
			response.setHeader("Cache-Control", "no-cache");// 没有缓存，立即返回响应
			PrintWriter out = response.getWriter();
			out.print(jsonArray);// 不能用println
//			System.out.println("jsonArray ====== " + jsonArray);
			out.flush();
			out.close();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
	}


	@Override
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// Printwriter for writing out responses to browser
//		System.out.println("request.getRequestURI() =========== " + request.getRequestURI());
		PrintWriter out = response.getWriter();

		if(!plugin.validate(request, response)){
			return;
		}
		String type = request.getParameter("actionType");
		if ("getAllUsers".equals(type)) { // 获取所有用户
			doGetAllUsers(request, response);
			return;
		} else if("showUserPage".equals(type)){
			showUserPage(request, response);
			return;
		} else if("updateGroupSortNumber".equals(type)){
			String groupName = request.getParameter("groupName");
			if(groupName == null || "".equals(groupName)){
				replyMessage("IllegalArgumentException", response);
				return;
			}
			String sortNumberStr = request.getParameter("sortNumber");
			int sortNumber = -1; // 排序号
			if(sortNumberStr != null && !"".equals(sortNumberStr)){
				try {
					sortNumber = Integer.parseInt(sortNumberStr);
				} catch (NumberFormatException e) {
					// ignore
				}
			}
			plugin.updateGroupSortNumber(groupName, sortNumber);
			replyMessage("ok", response);
			return;
		} else if ("synchro".equals(type)) {
			synchronizeUsers();
			replyMessage("ok", response);
			return;
		}
		
		
		String username = request.getParameter("userName");
		String password = request.getParameter("password");
		String name = request.getParameter("name");
		String email = request.getParameter("email");
		String groupNames = request.getParameter("groups");
		String sortNumberStr = request.getParameter("sortNumber");
		
		int sortNumber = -1; // 排序号
		if(sortNumberStr != null && !"".equals(sortNumberStr)){
			try {
				sortNumber = Integer.parseInt(sortNumberStr);
			} catch (NumberFormatException e) {
				// ignore
			}
		}
//		 else {
//				sortNumber = SequenceGenerator.nextInt(); // 获取下一个序列号
//			}
		
		
		// No defaults, add, delete, update only
		// type = type == null ? "image" : type;


		// Some checking is required on the username
		if (username == null) {
			replyMessage("IllegalArgumentException", response);
			return;
		}

		// Check the request type and process accordingly
		try {
			username = username.trim().toLowerCase();
			username = JID.escapeNode(username);
			username = Stringprep.nodeprep(username);
			if ("add".equals(type)) {
				plugin.createUser(username, password, name, email, groupNames, sortNumber);
				replyMessage("ok", response);
				// imageProvider.sendInfo(request, response, presence);
			} else if ("delete".equals(type)) {
				plugin.deleteUser(username);
				replyMessage("ok", response);
				// xmlProvider.sendInfo(request, response, presence);
			} else if ("enable".equals(type)) {
				plugin.enableUser(username);
				replyMessage("ok", response);
			} else if ("disable".equals(type)) {
				plugin.disableUser(username);
				replyMessage("ok", response);
				
			} else if ("update".equals(type)) {
				plugin.updateUser(username, password, name, email, groupNames, sortNumber);
				replyMessage("ok", response);
				// xmlProvider.sendInfo(request, response, presence);
			} else {
				log.warn("The userService servlet received an invalid request of type: "
						+ type);
			}
		} catch (UserAlreadyExistsException e) {
			replyMessage("UserAlreadyExistsException", response);
		} catch (UserNotFoundException e) {
			replyMessage("UserNotFoundException", response);
		} catch (IllegalArgumentException e) {
			replyMessage("IllegalArgumentException", response);
		} catch (Exception e) {
			replyMessage(e.toString(), response);
		}
	}

	/**
	 * 同步用户
	 * <br>2013-7-17 下午4:27:02
	 */
	private void synchronizeUsers(){
		SynchroUsers.synchroUsers();
	}
	
	private void replyMessage(String message, HttpServletResponse response) {
		try {
			PrintWriter out = response.getWriter();
			response.setContentType("text/plain");
			out.print(message);
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}
